package sk.fiit.lulco.grafy;

import java.util.Comparator;
import java.util.Random;

import sk.fiit.lulco.grafy.HEALConstants.SortType;

abstract class GraphComparator implements Comparator<Graph> {
	private SortType type;
	
	public GraphComparator(SortType sort) {
		this.type = sort;
	}
	
	public SortType getType() {
		return this.type;
	}
	
	/**
	 * compare method
	 * 
	 * @param	Vertex	vertex1
	 * @param	Vertex	vertex2
	 * @return	int
	 */
	public int compare(Graph graph1, Graph graph2) {
		switch (this.type) {
			case ASC: return compareGraphs(graph1, graph2);
			case DESC: return -compareGraphs(graph1, graph2);
		}
		return 0;
	}
	
	protected abstract int compareGraphs(Graph graph1, Graph graph2);
}

/**
 * class for graph comparing by fitness
 */
class GraphFitnessComparator extends GraphComparator {
	
	public GraphFitnessComparator(SortType sort) {
		super(sort);
	}

	/**
	 * compare method
	 * 
	 * @param	Graph	graph1
	 * @param	Graph	graph2
	 * @return	int
	 */
	public int compareGraphs(Graph graph1, Graph graph2) {
		if (graph1.getFitness() > graph2.getFitness()) {
			return 1;
		} else if (graph1.getFitness() < graph2.getFitness()) {
			return -1;
		} else {
			// because of this is the combination of more comparators, we have to
			// change sort type for those comparators which uses the same sort type as is defined
			SortType type;
			if (this.getType() == HEALConstants.SortType.ASC) {
				type = HEALConstants.SortType.ASC;
			} else {
				type = HEALConstants.SortType.DESC;
			}
			GraphColorComparator gcc = new GraphColorComparator(type);
			return gcc.compare(graph1, graph2);
		}
	}
}

/**
 * class for graph comparing by fitness
 */
class GraphColorComparator extends GraphComparator {
	
	public GraphColorComparator(SortType sort) {
		super(sort);
	}

	/**
	 * compare method
	 * 
	 * @param	Graph	graph1
	 * @param	Graph	graph2
	 * @return	int
	 */
	public int compareGraphs(Graph graph1, Graph graph2) {
		if (graph1.getColors(null).size() > graph2.getColors(null).size()) {
			return 1;
		} else if (graph1.getColors(null).size() < graph2.getColors(null).size()) {
			return -1;
		} else {
			return 0;
		}
	}
}

/**
 * class for graph comparing by fitness
 */
class GraphRandomComparator extends GraphComparator {
	
	public GraphRandomComparator(SortType sort) {
		super(sort);
	}

	/**
	 * compare method
	 * 
	 * @param	Graph	graph1
	 * @param	Graph	graph2
	 * @return	int
	 */
	public int compareGraphs(Graph graph1, Graph graph2) {
		Random randomGenerator = new Random();
		return randomGenerator.nextInt(3) - 1;
	}
}